package com.night.attendance.serviceImpl;

import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.night.attendance.DistException;
import com.night.attendance.DistNotFoundException;
import com.night.attendance.mapper.StudentAttendanceMapper;
import com.night.attendance.service.StudentAttendanceService;
import com.night.common.entity.PageBean;
import com.night.common.entity.attendance.AttendanceInfoDO;
import com.night.common.entity.attendance.StudentAttendanceDO;
import com.night.common.entity.attendance.StudentAttendanceQueryDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

/**
 * @author Dark-Morning
 * 2022/10/20 12:06
 */
@SuppressWarnings("all")
@Service
public class StudentAttendanceServiceImpl implements StudentAttendanceService {
    @Autowired
    StudentAttendanceMapper studentAttendanceMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Transactional(rollbackFor = Exception.class)
    public void attendance(AttendanceInfoDO attendanceInfoDO) {
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        double x = Double.parseDouble(attendanceInfoDO.getLng());
        double y = Double.parseDouble(attendanceInfoDO.getLat());
        String studentIndexKey = UUID.randomUUID().toString().replace("-", "");
        geoOperations.add(attendanceInfoDO.getRedisKey(), new Point(x, y), studentIndexKey);
        Distance dist = geoOperations.distance(attendanceInfoDO.getRedisKey(), "o", studentIndexKey, RedisGeoCommands.DistanceUnit.METERS);
        if(dist == null){
            throw new DistNotFoundException();
        }
        if (dist.getValue() > attendanceInfoDO.getSignArea()) {
            throw new DistException();
        }
        StudentAttendanceDO studentAttendanceDO = new StudentAttendanceDO();
        studentAttendanceDO.setAttendanceConfigId(attendanceInfoDO.getAttendanceConfigId());
        studentAttendanceDO.setSignTime(DateUtil.now());
        studentAttendanceDO.setStudentId(attendanceInfoDO.getStudentId());
        studentAttendanceDO.setSignState("1");
        studentAttendanceMapper.updateAttendance(studentAttendanceDO);
    }

    @Override
    public Integer getById(StudentAttendanceDO studentAttendanceDO) {
        return studentAttendanceMapper.selectById(studentAttendanceDO);
    }

    @Override
    public List<StudentAttendanceDO> listAttendanceRecord(StudentAttendanceQueryDO studentAttendanceQueryDO) {
        return studentAttendanceMapper.selectByCourse(studentAttendanceQueryDO);
    }

    @Override
    public void listStudentAttendance(StudentAttendanceQueryDO studentAttendanceQueryDO) {
        PageBean<List<StudentAttendanceDO>> pageBean = studentAttendanceQueryDO.getPageBean();
        Page<StudentAttendanceDO> p = PageHelper.startPage(pageBean.getCurrPage(), pageBean.getPageSize());
        List<StudentAttendanceDO> data = studentAttendanceMapper.selectShortAttendanceRecord(studentAttendanceQueryDO);
        pageBean.setData(data);
        pageBean.setTotalNum((int) p.getTotal());
        pageBean.setTotalPages(p.getPages());

    }

    @Override
    public void updateStudentAttendance(StudentAttendanceDO studentAttendanceDO) {
        studentAttendanceMapper.updateAttendance(studentAttendanceDO);
    }

}
